package info.ferrarimarco.itEbooksDownloader;

import info.ferrarimarco.itEbooksDownloader.controller.BookDownloaderTask;
import info.ferrarimarco.itEbooksDownloader.controller.BookNameDownloaderTask;
import info.ferrarimarco.java.helper.io.IoHelper;
import info.ferrarimarco.java.helper.portability.PropertiesHelper;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Index {

	private final static String destinationPath = "download";
	private final static String namesFilePath = destinationPath + "\\names.txt";
	private final static String downloadErrorsPath = destinationPath + "\\downloadErrors.txt";
	
	private static File saveDir;
	
	public static void main(String[] args){
		
		saveDir = new File(destinationPath);
		
		if (!saveDir.exists()) {
			saveDir.mkdir();
		}
		
		downloadNames(Integer.parseInt(args[0]), Integer.parseInt(args[1]), 4);
		downloadBooks(4);
	}
	
	private static void downloadNames(int firstBookIndex, int lastBookIndex, int threads) {

		int booksPerThread = (lastBookIndex - firstBookIndex) / threads;
		
		if((lastBookIndex - firstBookIndex) % threads > 0){
			threads++;
		}
		
		Thread[] threadsPool = new Thread[threads];
		BookNameDownloaderTask[] runnablesPool = new BookNameDownloaderTask[threads];
		
		String tagStart = "<title>";
		String tagEnd = " -";
		int startIndex = firstBookIndex;
		int endIndex = 0;
		
		for(int i = 0; i < threadsPool.length; i++){
			
			endIndex = startIndex + booksPerThread;
			
			// Corrections for last thread
			if(endIndex > lastBookIndex){
				endIndex = lastBookIndex;
			}
			
			if(endIndex - startIndex >= 0){
				runnablesPool[i] = new BookNameDownloaderTask(startIndex, endIndex, tagStart, tagEnd);
				threadsPool[i] = new Thread(runnablesPool[i]);
			}else{
				break;
			}
			
			startIndex = endIndex + 1;
		}
		
		for(int i = 0; i < threadsPool.length; i++){
			if(threadsPool[i] != null){
				threadsPool[i].start();			
			}
		}
		
		for(int i = 0; i < threadsPool.length; i++){
			try {
				if(threadsPool[i] != null){
					threadsPool[i].join();			
				}
			} catch (InterruptedException e) {
				System.out.println("No Join Possible");
			}
		}
		
		Collection<String> results = new ArrayList<String>(lastBookIndex);
		results.add(PropertiesHelper.getSystemLineSeparator());
		
		for(int i = 0; i < runnablesPool.length; i++){
			if(threadsPool[i] != null){
				results.addAll(runnablesPool[i].getResult());			
			}
		}
		
		try {
			IoHelper.writeCollectionToFile(results, namesFilePath, true);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void downloadBooks(int threads) {
		
		Thread[] threadsPool = new Thread[threads];
		BookDownloaderTask[] runnablesPool = new BookDownloaderTask[threads];
		
		String tagStart = "<a id=\"dl\" href=\"";
		String tagEnd = "\" rel=\"nofollow\">";
		
		String baseUrl = "http://it-ebooks.info";
		
        List<String> bookNames = null;
        
        try {
                bookNames = IoHelper.readListFromFile(namesFilePath);
        } catch (IOException e1) {
                e1.printStackTrace();
        }
        
		int booksPerThread = bookNames.size() / threads;
		
		if((bookNames.size() % threads > 0)){
			threads++;
		}
        
		int startIndex = 0;
		int endIndex = 0;
		
		for(int i = 0; i < threadsPool.length; i++){
			
			endIndex = startIndex + booksPerThread;
			
			// Corrections for last thread
			if(endIndex > bookNames.size() - 1){
				endIndex = bookNames.size() - 1;
			}
			
			if(endIndex - startIndex >= 0){
				runnablesPool[i] = new BookDownloaderTask(startIndex, endIndex, tagStart, tagEnd, destinationPath + "\\", bookNames, baseUrl);
				threadsPool[i] = new Thread(runnablesPool[i]);
			}else{
				break;
			}
			
			startIndex = endIndex + 1;
		}
		
		for(int i = 0; i < threadsPool.length; i++){
			if(threadsPool[i] != null){
				threadsPool[i].start();			
			}
		}
		
		for(int i = 0; i < threadsPool.length; i++){
			try {
				if(threadsPool[i] != null){
					threadsPool[i].join();			
				}
			} catch (InterruptedException e) {
				System.out.println("No Join Possible");
			}
		}
		
		Collection<String> results = new ArrayList<String>(bookNames.size());
		
		for(int i = 0; i < runnablesPool.length; i++){
			if(threadsPool[i] != null){
				results.addAll(runnablesPool[i].getResult());		
			}
		}
		
		try {
			IoHelper.writeCollectionToFile(results, downloadErrorsPath);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}
